﻿#region Using

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Commons.Diagnostics;
using SapFramework.Interface.Controls.Items.Base;

#endregion

namespace SapFramework.Queries
{
    /// <summary>
    /// Armazena consultas pré-determinadas para o sistema, relacionadas a itens de formulário do PadaOne.
    /// </summary>
    public static class ItemQueries
    {
        /// <summary>
        /// Recupera uma lista conténdo as classes que herdam da classe Item e não são abstratas.
        /// </summary>
        /// <returns>Lista de classes que herdam de Item</returns>
        public static IEnumerable<Type> GetSpecificItemClasses()
        {
            return
                from
                    sAssembly in AppDomain.CurrentDomain.GetAssemblies()
                where
                    sAssembly.GetName().Name == "SapFramework"
                from
                    sObjType in sAssembly.GetTypes()
                where
                    typeof(Item).IsAssignableFrom( sObjType ) && !sObjType.IsAbstract
                select
                    sObjType;
        }

        /// <summary>
        /// Recupera os eventos que fazem parte do tipo de um Item.
        /// </summary>
        /// <param name="aItemType">Tipo do Item</param>
        /// <returns>Uma lista dos eventos pertencentes aquele tipo de Item.</returns>
        public static IEnumerable<EventInfo> GetItemEventMembers( Type aItemType )
        {
            Debug.Assert.IsAssignableFrom( typeof(Item), () => aItemType );

            return
                from
                    sEvent in aItemType.GetEvents( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance )
                select
                    sEvent;
        }

        /// <summary>
        /// Recupera um dicionário conténdo todos os tipos de itens e seus respectivos eventos.
        /// </summary>
        /// <returns>Dicionário com chave pelo tipo do item e valores contendo uma lista de eventos daquele tipo de item.</returns>
        public static Dictionary<Type, IEnumerable<EventInfo>> GetEventsByItemTypes()
        {
            Dictionary<Type, IEnumerable<EventInfo>> lDctTypeEvents = new Dictionary<Type, IEnumerable<EventInfo>>();

            IEnumerable<Type> lEnmItemType = ItemQueries.GetSpecificItemClasses();

            foreach ( Type lType in lEnmItemType )
            {
                IEnumerable<EventInfo> lEnmItemEvents = ItemQueries.GetItemEventMembers( lType );

                lDctTypeEvents.Add( lType, lEnmItemEvents );
            }

            return lDctTypeEvents;
        }
    }
}